//
// Created by ECNU on 2024/2/21.
//

#ifndef NANO_FAISS_DISTANCES_H
#define NANO_FAISS_DISTANCES_H

#include <nanofaiss/impl/platform_macros.h>
#include <nanofaiss/utils/Heap.h>

#include <stdint.h>


namespace faiss {

/// squared L2 distance between x and y
float fvec_L2sqr(const float *x, const float *y, size_t d);

/** squared norm of a vector */
float fvec_norm_L2sqr(const float* x, size_t d);

void fvec_norms_L2sqr(float *norms, const float *x, size_t d, size_t nx);


/** compute the L2 norms for a set of vectors
 *
 * @param  norms    output norms, size nx
 * @param  x        set of vectors, size nx * d
 */
void fvec_norms_L2(float* norms, const float* x, size_t d, size_t nx);

/// same as fvec_norms_L2, but computes squared norms
void fvec_norms_L2sqr(float* norms, const float* x, size_t d, size_t nx);

// real call function for the knn_L2sqr
void knn_L2sqr(
        const float* x,
        const float* y,
        size_t d,
        size_t nx,
        size_t ny,
        size_t k,
        float* distances,
        int64_t* indexes,
        const float* y_norm2 = nullptr);

/** select the nearest k neighbor of x from y
 * @param x         query vector (d * nx)
 * @param y         base vector (d * ny)
 * @param d         vector dimension
 * @param nx        number of query vector
 * @param ny        number of base
 * @param res       result heap
 * @param y_norm    whether used optimized L2
 */
void knn_L2sqr(
        const float *x,
        const float *y,
        size_t d,
        size_t nx,
        size_t ny,
        float_query_t *qp,
        const float *y_norm = nullptr);



}
#endif // NANO_FAISS_DISTANCES_H
